/*
 * Copyright DataStax, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.gitee.wsl.jvm.struct.bits

import com.gitee.wsl.lang.bits.AbstractBitSet
import com.gitee.wsl.lang.bits.DocIdSetIterator

/**
 * A [AbstractBitSet] implementation that grows as needed to accommodate set(index) calls. When it
 * does so, it will grow its internal storage multiplicatively, assuming that more growth will be
 * needed in the future. This is the important difference from FixedBitSet + FBS.ensureCapacity,
 * which grows the minimum necessary each time.
 *
 *
 * For thread-safe version see [ThreadSafeGrowableBitSet].
 */
class GrowableBitSet : AbstractBitSet {
    private val bitSet: java.util.BitSet

    constructor(bitSet: java.util.BitSet) {
        this.bitSet = bitSet
    }

    constructor(initialBits: Int) {
        bitSet = java.util.BitSet(initialBits)
    }

    override fun clear(index: Int) {
        bitSet.clear(index)
    }

    override fun clear() {
        bitSet.clear()
    }

    override fun get(index: Int): Boolean {
        return bitSet[index]
    }

    override fun getAndSet(index: Int): Boolean {
        val v = get(index)
        set(index)
        return v
    }

    override fun length(): Int {
        return bitSet.length()
    }

    override fun set(i: Int) {
        bitSet.set(i)
    }

    override fun clear(startIndex: Int, endIndex: Int) {
        if (startIndex == 0 && endIndex == bitSet.length()) {
            bitSet.clear()
            return
        } else if (startIndex >= endIndex) {
            return
        }
        bitSet.clear(startIndex, endIndex)
    }

    override fun cardinality(): Int {
        return bitSet.cardinality()
    }

    override fun approximateCardinality(): Int {
        return bitSet.cardinality()
    }

    override fun prevSetBit(index: Int): Int {
        return bitSet.previousSetBit(index)
    }

    override fun nextSetBit(i: Int): Int {
        var next = bitSet.nextSetBit(i)
        if (next == -1) {
            next = NO_MORE_DOCS
        }
        return next
    }

    override fun clone(): AbstractBitSet {
        return GrowableBitSet(bitSet.clone() as java.util.BitSet)
    }

    override fun ramBytesUsed(): Long {
        throw UnsupportedOperationException()
    }
}
